package cn.initcap.algorithm.swing.sweeper;

import cn.initcap.algorithm.swing.AlgoVisHelper;
import cn.initcap.algorithm.swing.BaseAlgoFrame;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.SwingUtilities;

/**
 * @author initcap
 * @date 8/1/19 12:11 PM
 */
public class AlgoVisualizer {

    private static int DELAY = 5;
    private static int blockSide = 32;
    private MineSweeperData data;
    private BaseAlgoFrame frame;

    public AlgoVisualizer(int n, int m, int mineNumber) {

        data = new MineSweeperData(n, m, mineNumber);
        int sceneWidth = m * blockSide;
        int sceneHeight = n * blockSide;

        EventQueue.invokeLater(() -> {
            frame = new BaseAlgoFrame("Mine Sweeper", sceneWidth, sceneHeight) {
                @Override
                public void draw(Graphics graphics) {
                    Graphics2D g2d = (Graphics2D) graphics;
                    int w = sceneWidth / data.M();
                    int h = sceneHeight / data.N();

                    for (int i = 0; i < data.N(); i++) {
                        for (int j = 0; j < data.M(); j++) {

                            if (data.open[i][j]) {
                                if (data.isMine(i, j)) {
                                    AlgoVisHelper.putImage(g2d, j * w, i * h, MineSweeperData.MINE_IMAGE_URL);
                                } else {
                                    AlgoVisHelper.putImage(g2d, j * w, i * h, MineSweeperData.numberImageURL(data.getNumber(i, j)));
                                }
                            } else {
                                if (data.flags[i][j]) {
                                    AlgoVisHelper.putImage(g2d, j * w, i * h, MineSweeperData.FLAG_IMAGE_URL);
                                } else {
                                    AlgoVisHelper.putImage(g2d, j * w, i * h, MineSweeperData.BLOCK_IMAGE_URL);
                                }
                            }
                        }
                    }
                }
            };
            frame.addMouseListener(new AlgoMouseListener());
            new Thread(() -> {
                run();
            }).start();
        });
    }

    public static void main(String[] args) {

        int n = 20;
        int m = 20;
        int mineNumber = 20;

        new AlgoVisualizer(n, m, mineNumber);
    }

    public void run() {

        this.setData(false, -1, -1);

    }

    private void setData(boolean isLeftClicked, int x, int y) {
        if (isLeftClicked) {
            if (data.inArea(x, y)) {
                if (data.isMine(x, y)) {
                    // Game Over
                    data.open[x][y] = true;
                } else {
                    data.open(x, y);
                }
            }
        } else {
            if (data.inArea(x, y))
            // data.flags[x][y] = true;
            {
                data.flags[x][y] = !data.flags[x][y];
            }
        }

        frame.render(data);
        AlgoVisHelper.pause(DELAY);
    }

    public void addAlgoMouseListener() {
        frame.addMouseListener(new AlgoMouseListener());
    }

    private class AlgoMouseListener extends MouseAdapter {

        @Override
        public void mouseReleased(MouseEvent event) {

            event.translatePoint(
                    -(int) (frame.getBounds().width - frame.getCanvasWidth()),
                    -(int) (frame.getBounds().height - frame.getCanvasHeight())
            );

            Point pos = event.getPoint();

            int w = frame.getCanvasWidth() / data.M();
            int h = frame.getCanvasHeight() / data.N();

            int x = pos.y / h;
            int y = pos.x / w;
            // System.out.println(x + " , " + y);

            if (SwingUtilities.isLeftMouseButton(event)) {
                setData(true, x, y);
            } else if (SwingUtilities.isRightMouseButton(event)) {
                setData(false, x, y);
            }

        }
    }
}
